package com.xbongbong.paas.service.stage.jump;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.help.StageDetailHelp;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageJumpHandle;
import com.xbongbong.paas.service.stage.StageLogHandle;
import com.xbongbong.paas.service.stage.StageLogHandleFactory;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.factory.StageExecuteFactory;
import com.xbongbong.parent.interfaces.StageExecuteHandle;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpDealDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpValidateDTO;
import com.xbongbong.pro.businesstage.pojo.vo.StageJumpDealVO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.PaasStageEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.help.StageHelp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Auther: yingjianfeng
 * @Date: 2021/12/3 11:08
 * @Description: 取消阶段跳转策略
 */
@Slf4j
@Service("cancelStageJumpHandleImpl")
public class CancelStageJumpHandleImpl extends AbstractStageJumpHandle implements StageJumpHandle {

    @Resource
    private StageExecuteFactory stageExecuteFactory;
    @Resource
    private StageLogHandleFactory stageLogHandleFactory;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private StageDetailHelp stageDetailHelp;
    @Resource
    private StageHelp stageHelp;



    @Override
    public Integer type() {
        return StageTypeEnum.CANCEL_STAGE.getType();
    }

    @Override
    public StageJumpDealVO jumpDeal(StageJumpDealDTO stageJumpDealDTO) throws XbbException {
        // 跳入取消阶段处理
        try {
            log.info("===========跳转至取消阶段===========");
            Integer saasMark = stageJumpDealDTO.getSaasMark();
            Integer businessType = stageJumpDealDTO.getBusinessType();
            Long dataId = stageJumpDealDTO.getDataId();
            PaasStageEntity fromStageEntity = stageJumpDealDTO.getFromStageEntity();
            PaasStageEntity toStageEntity = stageJumpDealDTO.getToStageEntity();
            List<PaasStageEntity> rangeStageEntitys = stageJumpDealDTO.getRangeStageEntitys();
            if (Objects.nonNull(fromStageEntity)) {
                rangeStageEntitys.add(fromStageEntity);
            }
            rangeStageEntitys.add(toStageEntity);
            String corpid = stageJumpDealDTO.getCorpid();
            Long formId = stageJumpDealDTO.getFormId();
            StageProcessEntity stageProcessEntity = stageJumpDealDTO.getStageProcessEntity();
            String memo = stageJumpDealDTO.getMemo();
            Integer reasonId = stageJumpDealDTO.getReasonId();
            String stageAttr = stageJumpDealDTO.getStageAttr();
            Boolean isNew = stageJumpDealDTO.getIsNew();
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
            StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
            List<Long> stageIdIn = new ArrayList();
            for (PaasStageEntity temp : rangeStageEntitys) {
                stageIdIn.add(temp.getId());
            }
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 初始化一下开始阶段的sort
            Integer fromSort = 99;
            Integer toSort = toStageEntity.getSort();
            if (Objects.nonNull(fromStageEntity)) {
                fromSort = fromStageEntity.getSort();
            }
            Long now = DateTimeUtil.getInt();
            Long toStageId = toStageEntity.getId();
            StageLogEntity stageLogEntity = new StageLogEntity();
            // 更新一下from的stagelog  还需要判断下tostagelog是否是第一次进入
            // 可能是第一次跳入失败阶段，不管先查一下
            params.clear();
            params.put("corpid", corpid);
            params.put("formId", formId);
            params.put("dataId", dataId);
            params.put("stageId", toStageId);
//                params.put("del", 0);   // 不拼del查  有可能之前跳入过 然后回退或激活了
            List<StageLogEntity> stageLogEntities = stageLogHandle.findEntitys(params);
            // 区间log
            List<StageLogEntity> rangeStageLogEntitys = new ArrayList<>();
            StageLogEntity nowStageLogEntity = null;
            StageLogEntity toStageLogEntity = null;
            // 获取区间和 from的stagelog
            if (CollectionsUtil.isNotEmpty(stageIdIn)) {
                params.clear();
                params.put("corpid", corpid);
                params.put("formId", formId);
                params.put("dataId", dataId);
                params.put("stageIdIn", stageIdIn);
                params.put("del", 0);
                List<StageLogEntity> tempStageLogEntities = stageLogHandle.findEntitys(params);
                for (StageLogEntity temp : tempStageLogEntities) {
                    Long stageId = temp.getStageId();
                    Integer isNow = temp.getIsNow();
                    if (Objects.equals(isNow, 1)) {
                        nowStageLogEntity = temp;
                    } else if (Objects.equals(stageId, toStageEntity.getId())) {
                        rangeStageLogEntitys.add(temp);
                    } else {
                        rangeStageLogEntitys.add(temp);
                    }

                }
            }
            // 不是从开始阶段跳过来的
            if (fromSort < toSort) {
                // 后退操作
                // 后退需要将之间的普通阶段的log更新一下
                /*if (CollectionsUtil.isNotEmpty(rangeStageLogEntitys)) {
                    stageLogHandle.deleteBatch(rangeStageLogEntitys, corpid);
                }*/
                //
                if (Objects.nonNull(nowStageLogEntity)) {
                    nowStageLogEntity.setOutTime(0L);
                    nowStageLogEntity.setIsNow(0);
                    //计算规则为history_stay_time=history_stay_time+out_time-into_time
                    nowStageLogEntity.setHistoryStayTime(nowStageLogEntity.getHistoryStayTime() + now - nowStageLogEntity.getIntoTime());
                    stageLogHandle.save(nowStageLogEntity);
                }
            } else {
                // 判断下是否是开始阶段过来的
                if (Objects.nonNull(nowStageLogEntity)) {
                    // 前进操作
                    nowStageLogEntity.setOutTime(now);
                    //计算规则为history_stay_time=history_stay_time+out_time-into_time
                    nowStageLogEntity.setHistoryStayTime(nowStageLogEntity.getHistoryStayTime() + now - nowStageLogEntity.getIntoTime());
                    nowStageLogEntity.setIsNow(0);
                    stageLogHandle.save(nowStageLogEntity);
                }
            }
            if (CollectionsUtil.isEmpty(stageLogEntities)) {
                // 空的 说明第一次进入 需要new一个stagelog
                stageLogEntity.setCorpid(corpid);
                stageLogEntity.setFormId(formId);
                stageLogEntity.setStageProcessId(stageProcessEntity.getId());
                stageLogEntity.setStageId(toStageId);
                stageLogEntity.setStageType(toStageEntity.getType());
                stageLogEntity.setStageCode(toStageEntity.getCode());
                stageLogEntity.setDataId(dataId);
                stageLogEntity.setIsNow(1);
                if (Objects.nonNull(fromStageEntity)) {
                    stageLogEntity.setPreStageId(fromStageEntity.getId());  //记录客户流失前阶段id
                    stageLogEntity.setBeforeStageCode(fromStageEntity.getCode());    // 记录客户流失前阶段code
                }
                if (Objects.nonNull(reasonId)) {
                    stageLogEntity.setReasonId(reasonId);  //流失原因/输单原因/无效原因的数据字典id
                }
                stageLogEntity.setMemo(memo == null ? "" : memo);  // 流失备注
                stageLogEntity.setIntoTime(now);
                stageLogEntity.setOutTime(0L);
//                    stageLogEntity.setLastIntoTime(0); //上次进入该时间
                stageLogEntity.setHistoryStayTime(0L);
                stageLogEntity.setAddTime(now);
                stageLogEntity.setUpdateTime(now);
                stageLogEntity.setDel(0);
                // 保存
                stageLogHandle.save(stageLogEntity);
            } else {
                // 非空 需要将del置为0
                stageLogEntity = stageLogEntities.get(0);
                stageLogEntity.setIsNow(1);
                if (Objects.nonNull(reasonId)) {
                    stageLogEntity.setReasonId(reasonId);  //流失原因/输单原因/无效原因的数据字典id
                }
                stageLogEntity.setMemo(memo == null ? "" : memo);  // 流失备注
                stageLogEntity.setLastIntoTime(stageLogEntity.getIntoTime()); //上次进入该时间
                stageLogEntity.setIntoTime(now);
                stageLogEntity.setOutTime(0L);
                stageLogEntity.setHistoryStayTime(0L);
                stageLogEntity.setUpdateTime(now);
                stageLogEntity.setDel(0);
                if (fromStageEntity != null) {
                    stageLogEntity.setPreStageId(fromStageEntity.getId());  //记录客户流失前阶段id
                    stageLogEntity.setBeforeStageCode(fromStageEntity.getCode());    // 记录客户流失前阶段code
                }
                // 更新
                stageLogHandle.save(stageLogEntity);
            }
            // 更新比例
            // 解释阶段没有word的 直接取跳出比例
            JSONObject jsonObject = new JSONObject();
//            Integer proportion = stageDetailHelp.calculateProportion(corpid, formId, toStageId, stageLogEntity.getId(), stageExecute);
            jsonObject.put(PaasStageEnum.STAGE_RATIO.getAttr(), toStageEntity.getOutProportion());
            jsonObject.put(stageAttr, toStageEntity.getCode());
            jsonObject.put(PaasStageEnum.STAGE_ID.getAttr(), toStageId);
            //判断该公司是否支持停留时长功能，如果支持的话需要将阶段进入时间置入主数据
            if (stageHelp.isSupportStageStayTime(corpid)) {
                stageHelp.packageStageStayTime(corpid, formId, businessType, jsonObject, now, stageJumpDealDTO.getData());
            }
            if(Objects.isNull(fromStageEntity)){
                jsonObject.put(PaasStageEnum.STAGE_PROCESS_ID.getAttr(), stageProcessEntity.getId());
            }
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(dataId, jsonObject, corpid);
            proUpdateHelp.updateBatch(saasMark, businessType, corpid, Collections.singletonList(updateData));
        } catch (Exception e) {
            log.error("阶段跳转至失败阶段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return null;
    }

    @Resource
    private StageHandleFactory stageHandleFactory;


    @Override
    public void validate(StageJumpValidateDTO stageJumpValidateDTO) throws XbbException {
       //  机会的特殊校验
        StageProcessEntity stageProcessEntity = stageJumpValidateDTO.getStageProcessEntity();
        Long stageProcessId = stageProcessEntity.getId();
        PaasStageEntity fromStageEntity = stageJumpValidateDTO.getFromStageEntity();
        Integer fromStageType = stageJumpValidateDTO.getFromStageType();
        PaasStageEntity toStageEntity = stageJumpValidateDTO.getToStageEntity();
        Integer toStageType = stageJumpValidateDTO.getToStageType();
        String corpid = stageJumpValidateDTO.getCorpid();
        Long formId = stageJumpValidateDTO.getFormId();
        Integer businessType = stageJumpValidateDTO.getBusinessType();
        Integer saasMark = stageJumpValidateDTO.getSaasMark();
        Long dataId = stageJumpValidateDTO.getDataId();
        // 进入条件校验s
        String preCondition = stageDetailHelp.validateStagePreCondition(corpid, saasMark, businessType, formId, dataId, toStageEntity.getId());
        if(StringUtil.isNotEmpty(preCondition)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,preCondition);
        }

        // 跨阶段校验并设置rangeStage
        skipStageValidateAndSetRangeStage(stageJumpValidateDTO);

    }

    @Override
    public Integer getJumpIntoProportion(Long dataId, String corpid, Long formId, Long stageId, Integer saasMark, Integer businessType, Integer outProportion) throws XbbException {
        return outProportion;
    }
}
